<template>
  <div>
    <q-table
      flat
      bordered
      selection="multiple"
      v-model:selected="selectedModel"
      :visibleColumns="visibleColumns"
      :columns="columns"
      :rows="rows"
      :dense="$q.screen.lt.md"
      :filter="filter"
      v-bind:="$attrs"
      color="primary"
    >
      <!-- 头部 -->
      <template v-slot:top="props">
        <div class="row items-center full-width">
          <div v-if="defaultTableProps.title" class="text-bold mr-15px">
            {{ defaultTableProps.title }}
          </div>
          <!-- 外部具名插槽 -->
          <slot name="top-left" />
          <!-- 默认插槽 -->
          <slot name="top-default-content">
            <q-space />
            <q-input dense v-select-all-text v-model="filter" class="q-mr-md w-150px">
              <template v-slot:append>
                <q-icon name="search" />
              </template>
            </q-input>
            <q-select
              v-model="visibleColumns"
              multiple
              borderless
              dense
              options-dense
              display-value="筛选列"
              emit-value
              map-options
              :options="columns"
              option-value="name"
            />

            <q-btn
              flat
              round
              dense
              :icon="props.inFullscreen ? 'fullscreen_exit' : 'fullscreen'"
              @click="props.toggleFullscreen"
            />
            <q-btn flat round dense icon="archive" @click="handelExportTable" />
          </slot>
        </div>
      </template>

      <!-- 允许外部传递其他插槽 -->
      <template v-for="(_, slotName) in otherSlots" v-slot:[slotName]="slotProps">
        <slot :name="slotName" v-bind="slotProps" />
      </template>
    </q-table>
  </div>
</template>

<script setup lang="ts">
import { computed, ref, useAttrs, useSlots, watchEffect } from 'vue'
import { useQuasar } from 'quasar'
import type { QTableProps, QTableColumn } from 'quasar'
import { useTable } from 'src/hooks/useTable'

defineOptions({
  name: 'MiniTable',
})

// 1. 定义 Props
interface MiniTableProps {
  rows: QTableProps['rows']
  columns: QTableColumn[]
  selected?: any[] // 用于 v-model:selected
  rowKey?: string | ((row: any) => any)
}

const props = withDefaults(defineProps<MiniTableProps>(), {
  loading: false,
  selected: () => [], // 必须使用工厂函数
  rowKey: 'id',
})

// 2. 定义Emits（用于v-model）
const emit = defineEmits<{ (e: 'update:selected', value: any[]): void }>()

// 3. 使用useAttrs 获取所有透传属性
const attrs = useAttrs()
const $q = useQuasar()

// 4. 内部状态
const filter = ref('')
const visibleColumns = ref<string[]>([])

// 5. 组合式函数
// useTable 依赖于props.rows 和 props.columns

const { handelExportTable } = useTable(
  () => props.rows,
  () => props.columns,
)

// 6. 实现v-model:elected
const selectedModel = computed({
  get: () => props.selected,
  set: (value) => emit('update:selected', value),
})

// 7. 合并属性
const defaultTableProps = computed(() => {
  const defaults = {
    title: '',
    flat: true,
    bordered: true,
    selection: 'multiple' as QTableProps['selection'],
    'row-key': props.rowKey,
    'selected-rows-label': (count: number) => `已选择 ${count} 条记录`,
    color: 'primary',
    dense: $q.screen.lt.md,
  }
  return { ...defaults, ...attrs }
})

// 8. 监听columns变化
watchEffect(() => {
  if (props.columns) {
    visibleColumns.value = props.columns.map((col) => col.name)
  }
})

// 9. 插槽转发
const slots = useSlots()
const otherSlots = computed(() => {
  const { ...rest } = slots
  return rest
})
</script>

<style lang="scss"></style>
